﻿using System;
using System.Threading;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using SimpleServiceBus.Bus;
using SimpleServiceBus.Bus.MessageManagement.Callbacks;

namespace SimpleServiceBus.Tests.Bus.MessageManagement.Callbacks
{
    [TestFixture]
    public class BusAsyncResultTestFixture
    {
        [Test]
        public void Can_Create_Wait_And_Complete_BusAsyncResult()
        {
            bool cbExec = false;

            DateTime mark = DateTime.Now;

            BusAsyncResult ar = Wait_For_50_Milliseconds
                (
                myState =>
                {
                    cbExec = true;
                    Assert.That(((CompletionResult)myState.AsyncState).State, Is.EqualTo("Hi, I'm State"));
                }, "Hi, I'm State"
                );


            Assert.IsFalse(ar.IsCompleted);

            ar.AsyncWaitHandle.WaitOne();

            Assert.That(DateTime.Now.Subtract(mark), Is.GreaterThanOrEqualTo(TimeSpan.FromMilliseconds(50)));

            //Let the callback finish up, if necessary.
            Thread.Sleep(10);
            Assert.That(cbExec, Is.True);

            Assert.IsTrue(ar.IsCompleted);
        }

        private static BusAsyncResult Wait_For_50_Milliseconds(AsyncCallback cb, object state)
        {
            var ar = new BusAsyncResult(cb, state);
            new Timer((returnedAr => ((BusAsyncResult)returnedAr).Complete(0, null)), ar, 50, 1000);
            return ar;

        }
    }
}